#include "SharedMemory.h"


SharedMemory::SharedMemory()
{
    while (true)
    {
        // 1. 获取已存在的信号量
        sem_shm = semget((key_t)40001, 1, 0666);

        if (sem_shm == -1) 
        {
            cout << "等待信号量的创建》》" << endl;
            usleep(1000000);
        }
        else
        {
            break;
        }
    }

    //开辟一块共享内存
    shmid = shmget((key_t)20001, sizeof(ShmControl), IPC_CREAT | 0666);
    //连接共享内存
    shmaddr = shmat(shmid, NULL, 0);
    cout << "已连接共享内存" << endl;

    //创建生产者消息队列
    msgidA = msgget((key_t)111111, IPC_CREAT | 0666);

    //创建消费者消息队列
    msgidB = msgget((key_t)222222, IPC_CREAT | 0666);

    //初始化线程池
    threadPool = new ThreadPool();
    //初始化连接池
    connPool = ConnectionPool::getConnectPool();
    //共享信号量
    BaseTask::sem_shm = sem_shm;
    ReadMemory();
}


void SharedMemory::ReadMemory() {
    // 1. 连接共享内存
    ShmControl* shm = (ShmControl*)shmat(shmid, NULL, 0);
    if (shm == (void*)-1) {
        cerr << "共享内存连接失败: " << strerror(errno) << endl;
        throw std::runtime_error("共享内存连接失败");
    }

    while (true) {
       
        try {
            // 2. 安全读取消息（加消息队列锁）
             MSG msg = { 0 };
             if (msgrcv(msgidA, &msg, sizeof(MSG), 1, 0) == -1) {
                 if (errno != EINTR) {  // 忽略信号中断
                     cerr << "msgrcv失败: " << strerror(errno) << endl;
                 }
                 continue;
             }
            // 3. 处理共享内存（加共享内存锁）
            sem_p(sem_shm, 0); // P操作

            ShmBlock* block = &shm->blocks[msg.index];

            // 4. 验证块状态
            if (block->status != 1) {
                sem_v(sem_shm, 0); // 提前释放锁
                cerr << "无效块状态: " << block->status << endl;
                continue;
            }

            // 5. 读取数据
            HEAD head = { 0 };
            vector<char> body(MEMORYSIZE, 0);
            memcpy(&head, block->data, sizeof(HEAD));
            memcpy(body.data(), block->data + sizeof(HEAD), head.data_len);

            // 6. 重置块状态
            block->status = 0;
            memset(block->data, 0, MEMORYSIZE);

            sem_v(sem_shm, 0); // V操作

            // 7. 创建任务（不需要加锁）
            BaseTask* task = TaskFactory::getTask(
                head.service_type,
                body.data(),
                msg.client_fd,
                head.data_len,
                shmid,
                msgidB
            );

            if (task) {
                // 发送响应消息（加消息队列锁）
                threadPool->AddTask(task);
            }
            else {
                cerr << "任务创建失败: " << head.service_type << endl;
            }

        }
        catch (const exception& e) {
            // 确保异常时释放锁
            if (sem_shm != -1) sem_v(sem_shm, 0);
            cerr << "读取异常: " << e.what() << endl;
        }
    }

    // 8. 最终清理
    shmdt(shm);
}

SharedMemory::~SharedMemory()
{
    // 分离共享内存
    shmdt(shmaddr);
    // 删除共享内存（可选，根据需求决定是否删除）
    shmctl(shmid, IPC_RMID, NULL);
    // 删除消息队列
    msgctl(msgidA, IPC_RMID, NULL);
    msgctl(msgidB, IPC_RMID, NULL);
    // 清理线程池和连接池
    delete threadPool;
    // ConnectionPool的清理可能需要调用其特定方法
}

int SharedMemory::sem_p(int semid, int semindex) {
    struct sembuf buf = { semindex, -1, SEM_UNDO };
    if (semop(semid, &buf, 1) == -1) {
        perror("semop P failed");
        return -1;
    }
    return 0;
}

int SharedMemory::sem_v(int semid, int semindex) {
    struct sembuf buf = { semindex, 1, SEM_UNDO };
    if (semop(semid, &buf, 1) == -1) {
        perror("semop V failed");
        return -1;
    }
    return 0;
}